﻿#region [ Modification History ]
/*
 * 06/04/2013 Denis Kholine
 *  Add comments and license
 */
#endregion

#region  [ UIUC NCSA Open Source License ]
/*****************************************************************************\
 *             University of Illinois/NCSA Open Source License
 *
 * 
 *      Copyright © 2012,2013, The Board of Trustees of the University of Illinois. All rights reserved.
 *
 *      Developed by: Rakesh Bobba, Derek Dagit, Erich Heine, Denis Kholine,
 *                    Klara Nahrstedt, David Rodgers,   William H. Sanders, Tim Yardley
 *
 *      Information Trust Institute/Coordinated Science Laboratory
 * 
 *      University of Illinois
 *      
 *      The Board of Trustees of the University of Illinois
 *      109 Coble Hall
 *      801 South Wright Street
 *      Champaign, IL 61820-6242
 *
 *      http://www.iti.illinois.edu / http://csl.illinois.edu
 * 
 *      Permission is hereby granted, free of charge, to any person obtaining a copy of this software and 
 *      associated documentation files (the “Software”), to deal with the Software without restriction, 
 *      including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
 *      and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
 *      subject to the following conditions:
 *
 *      Redistributions of source code must retain the above copyright notice, this list of conditions and the
 *      following disclaimers.
 *      
 *      Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
 *      the following disclaimers in the documentation and/or other materials provided with the distribution.
 *
 *      Neither the names of Information Trust institute, Coordinated Science Laboratory, University of Illinois,
 *      The Board of Trustees of the University of Illinois nor the names of its contributors may be used to 
 *      endorse or promote products derived from this Software without specific prior written permission.
 *      
 *      THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
 *      LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN
 *      NO EVENT SHALL THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 *      WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 
 *      SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
 *      
 \*****************************************************************************/
#endregion

#region [ Using ]
using GSF;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using SIEGate.Core;
using SIEGate.Core.Stats;
using SIEGate.Core.Fakes;
using SIEGate.Core.Notifications;
using SIEGate.Core.Measurements;
using SIEGate.Core.Logging;
using SIEGate.Core.Legacy;
using SIEGate.Core.MessageBusses;
using GSF.TimeSeries.Transport;
using Microsoft.VisualStudio.TestTools.UnitTesting;
#endregion

namespace SIEGateCoreTest
{
    /// <summary>
    /// A NetworkCommunicator tests class
    /// </summary>
    [TestClass]
    public class NetworkCommunicatorTests
    {
        #region [ Members ]
        private MockNetworkCommunicator target;
        private MockMessageBusProxy busProxy;
        private MockNetworkCommunicator.NetworkCommunicatorInfoBase info;
        #endregion

        #region [ Methods ]
        /// <summary>
        /// A DefaultGet test
        /// </summary>
        [TestMethod]
        public void DefaultGetTest()
        { 
            busProxy = new MockMessageBusProxy();
            info = new NetworkCommunicator.NetworkCommunicatorInfoBase();
            target = new MockNetworkCommunicator(busProxy, info);
            HashSet<Guid> incoming = new HashSet<Guid>();
            HashSet<Guid> outgoing = new HashSet<Guid>();

            incoming.Add(Guid.NewGuid());
            outgoing.Add(Guid.NewGuid());

            info.IncomingStreamIDs = incoming;
            info.OutgoingStreamIDs = outgoing;

            target.Register();

            bool expected = true;
            bool actual = false;

            actual = (busProxy.Published.Count == 1 && busProxy.Subscribed.Count == 1);

            Assert.AreEqual(actual, expected);
        }

        /// <summary>
        /// A DefaultGetInfo test
        /// </summary>
        [TestMethod]
        public void DefaultGetInfoTest()
        {
            busProxy = new MockMessageBusProxy();
            info = new NetworkCommunicator.NetworkCommunicatorInfoBase();
            target = new MockNetworkCommunicator(busProxy, info);
            HashSet<Guid> incoming = new HashSet<Guid>();
            HashSet<Guid> outgoing = new HashSet<Guid>();
            Dictionary<string, string> settings = new Dictionary<string, string>();
            incoming.Add(Guid.NewGuid());
            outgoing.Add(Guid.NewGuid());

            info.IncomingStreamIDs = incoming;
            info.OutgoingStreamIDs = outgoing;

            string value = Guid.NewGuid().ToString();

            string key = incoming.Last().ToString();
            settings.Add(key, value);

            info.Settings = settings;
            string result = info.DefaultGet(key);

            bool expected = true;
            bool actual = (result == value);
            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        /// A UpdateBytesReceived
        /// </summary>
        [TestMethod]
        public void UpdateBytesReceivedTest()
        {
            busProxy = new MockMessageBusProxy();
            info = new NetworkCommunicator.NetworkCommunicatorInfoBase();
            target = new MockNetworkCommunicator(busProxy, info);

            HashSet<Guid> incoming = new HashSet<Guid>();
            HashSet<Guid> outgoing = new HashSet<Guid>();

            incoming.Add(Guid.NewGuid());
            outgoing.Add(Guid.NewGuid());

            info.IncomingStreamIDs = incoming;
            info.OutgoingStreamIDs = outgoing;

            target.Register();

            bool expected = true;
            bool actual = false;

            int bytes = 10;

            target.StubUpdateBytesReceived(bytes);

            Counter counter = target.StatsCluster.GetCounter("Bytes In") ;

            long result = (long)bytes;
            actual = (counter.CurrentAggregateValue == result);

            Assert.AreEqual(actual, expected);
        }

        /// <summary>
        /// A UpdateBytesSent
        /// </summary>
        [TestMethod]
        public void UpdateBytesSentTest()
        {
            busProxy = new MockMessageBusProxy();
            info = new NetworkCommunicator.NetworkCommunicatorInfoBase();
            target = new MockNetworkCommunicator(busProxy, info);

            HashSet<Guid> incoming = new HashSet<Guid>();
            HashSet<Guid> outgoing = new HashSet<Guid>();

            incoming.Add(Guid.NewGuid());
            outgoing.Add(Guid.NewGuid());

            info.IncomingStreamIDs = incoming;
            info.OutgoingStreamIDs = outgoing;

            target.Register();

            bool expected = true;
            bool actual = false;

            int bytes = 10;

            target.StubUpdateBytesSent(bytes);

            Counter counter = target.StatsCluster.GetCounter("Bytes Out");            

            long result = (long)bytes;
            actual = (counter.CurrentAggregateValue == result);

            Assert.AreEqual(actual, expected);
        }

        /// <summary>
        /// A InfoExtractConfiguration test.
        /// TODO: Adjust to filter what would be structure for DataSet?
        /// </summary>
        [TestMethod]
        public void InfoExtractConfigurationTest()
        {
            ConfigurationTables configurationTables = new ConfigurationTables();
            info = new NetworkCommunicator.NetworkCommunicatorInfoBase();
            info.Settings = new Dictionary<string, string>();
            info.Settings.Add("incomingStreamIDs", "inputMeasurementKeys");
            info.Settings.Add("outgoingStreamIDs", "outputMeasurementKeys"); 
            bool expected = true;
            bool actual = false;
            info.ExtractConfiguration(configurationTables.DataSetActionAdapter);
            actual = (info.IncomingStreamIDs.Count > 0);
            Assert.AreEqual(actual, expected);
        }

        /// <summary>
        /// A SetDefaults and DefaultsGet tests. 
        /// </summary>
        [TestMethod]
        public void SetGetDefaultsTest()
        {
            Dictionary<string,string> defaults = new Dictionary<string,string>();
            defaults.Add("incomingStreamID", Guid.NewGuid().ToString());
            info = new NetworkCommunicator.NetworkCommunicatorInfoBase();
            info.Settings = new Dictionary<string, string>();
            string ID = Guid.NewGuid().ToString();
            info.Settings.Add("incomingStreamIDs", ID);
            bool expected = true;
            bool actual = false;
            info.SetDefaults(defaults);
            actual = (info.DefaultGet("incomingStreamIDs") ==ID) ;
            Assert.AreEqual(actual, expected);
        }


        /// <summary>
        /// A runtime type test. 
        /// </summary>
        [TestMethod]
        public void RuntimeType_Tests()
        {
           
            info = new NetworkCommunicator.NetworkCommunicatorInfoBase();
            info.Settings = new Dictionary<string, string>();
            string ID = Guid.NewGuid().ToString();
            info.Settings.Add("incomingStreamIDs", ID);
            bool expected = true;
            bool actual = false;
            Type networkcommunicator = typeof(NetworkCommunicator);
            info.RuntimeType = networkcommunicator;

            actual = (info.RuntimeType == typeof(NetworkCommunicator));
            Assert.AreEqual(expected, actual);
            // Should throw an exception if type other than NetworkComunicator
            try
            {
                info.RuntimeType = typeof(object);
            }
            catch
            {
                actual = true;
            }
            Assert.AreEqual(expected, actual);
        }


        /// <summary>
        /// A Update type test. 
        /// </summary>
        [TestMethod]
        public void UpdateTest()
        {
            info = new NetworkCommunicator.NetworkCommunicatorInfoBase();
            Dictionary<string,string> settings = new Dictionary<string,string>();
            string ID = Guid.NewGuid().ToString();
            settings.Add("incomingStreamIDs",ID);
            info.Update(settings);
            bool expected = true;
            bool actual = (info.Settings == settings);
            Assert.AreEqual(expected, actual);
        }
        #endregion
    }
}
